﻿using System;
using System.IO;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.Windows;

namespace eLearning.Util
{
    public static class FileUtil
    {
        private static string boundary;

        public static byte[] ReadToEnd(System.IO.Stream stream)
        {
            long originalPosition = stream.Position;
            stream.Position = 0;

            try
            {
                byte[] readBuffer = new byte[4096];

                int totalBytesRead = 0;
                int bytesRead;

                while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                {
                    totalBytesRead += bytesRead;

                    if (totalBytesRead == readBuffer.Length)
                    {
                        int nextByte = stream.ReadByte();
                        if (nextByte != -1)
                        {
                            byte[] temp = new byte[readBuffer.Length * 2];
                            Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                            Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                            readBuffer = temp;
                            totalBytesRead++;
                        }
                    }
                }

                byte[] buffer = readBuffer;
                if (readBuffer.Length != totalBytesRead)
                {
                    buffer = new byte[totalBytesRead];
                    Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                }
                return buffer;
            }
            finally
            {
                stream.Position = originalPosition;
            }
        }

        public static void writeMultipartObject(Stream stream, object data, string bound)
        {
            boundary = bound;

            StreamWriter writer = new StreamWriter(stream);
            if (data != null)
            {
                foreach (var entry in data as Dictionary<string[], object>)
                {
                    WriteEntry(writer, entry.Key, entry.Value);
                }
            }
            writer.Write("--");
            writer.Write(boundary);
            writer.WriteLine("--");
            writer.Flush();
        }

        private static void WriteEntry(StreamWriter writer, string[] key, object value)
        {
            if (value != null)
            {
                writer.Write("--");
                writer.WriteLine(boundary);
                if (value is byte[])
                {
                    byte[] ba = value as byte[];

                    writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""; filename=""{1}""", key[0], key[1]);
                    writer.WriteLine(@"Content-Type: application/octet-stream");
                    //writer.WriteLine(@"Content-Type: image / jpeg");
                    writer.WriteLine(@"Content-Length: " + ba.Length);
                    writer.WriteLine();
                    writer.Flush();
                    Stream output = writer.BaseStream;

                    output.Write(ba, 0, ba.Length);
                    output.Flush();
                    writer.WriteLine();
                }
                else
                {
                    writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""", key[1]);
                    writer.WriteLine();
                    writer.WriteLine(value.ToString());
                }
            }
        }

        public static List<string> GetAllFilePaths()
        {
            IsolatedStorageFile storage = GetUserStorage();

            List<string> result = new List<string>();
            Stack<string> stack = new Stack<string>();

            // Add initial directory
            string initialDirectory = "*";
            stack.Push(initialDirectory);

            // Continue while there are directories to process
            while (stack.Count > 0)
            {
                string dir = stack.Pop();

                string directoryPath;
                if (dir == "*")
                {
                    directoryPath = "*";
                }
                else
                {
                    directoryPath = dir + @"\*";
                }

                // Add all files at this directory to the result List
                var filesInCurrentDirectory = storage.GetFileNames(directoryPath);

                List<string> filesInCurrentDirectoryWithFolderName = new List<string>();

                // Prefix the filename with the directory name
                foreach (string file in filesInCurrentDirectory)
                {
                    filesInCurrentDirectoryWithFolderName.Add(Path.Combine(dir, file));
                }

                result.AddRange(filesInCurrentDirectoryWithFolderName);

                // Add all directories at this directory
                foreach (string directoryName in storage.GetDirectoryNames(directoryPath))
                {
                    stack.Push(Path.Combine(dir, directoryName));
                }

            }

            return result;

        }

        public static Stream ReadFileStream(string file)
        {
            IsolatedStorageFile myIsolatedStorage = GetUserStorage();
            IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile(file, FileMode.Open, FileAccess.Read);
            return fileStream;
        }

        public static void CreateDirectory(string directoryName)
        {
            try
            {
                IsolatedStorageFile storage = GetUserStorage();
                if (!string.IsNullOrEmpty(directoryName) && !storage.DirectoryExists(directoryName))
                {
                    storage.CreateDirectory(directoryName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public static void DeleteDirectory(string directoryName)
        {
            try
            {
                IsolatedStorageFile storage = GetUserStorage();
                if (!string.IsNullOrEmpty(directoryName) && storage.DirectoryExists(directoryName))
                {
                    storage.DeleteDirectory(directoryName);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public static IsolatedStorageFile GetUserStorage()
        {
            return IsolatedStorageFile.GetUserStoreForApplication();
        }

    }
}
